/*
 * Realiza a leitura do Carousel disponibilizado pelo Provider
 */
package ObjectsManager;

import ProviderStreamWorker.Utils.ByteArray;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Fabrício Alves
 * @author Antônio Pedro
 */
public class CarouselReader extends Thread {

    private final String address;
    private final int port;

    public CarouselReader(String address, int port) {
        this("CarouselReaderThread", address, port);
    }

    public CarouselReader(String name, String address, int port) {
        super(name);
        this.address = address;
        this.port = port;
    }

    private void testWithMesages() throws IOException {
        try (MulticastSocket socket = new MulticastSocket(this.port)) {
            InetAddress group = InetAddress.getByName(this.address);
            socket.joinGroup(group);

            DatagramPacket packet;
            for (int i = 0; i < 100; i++) {
                byte[] buf = new byte[256];
                packet = new DatagramPacket(buf, buf.length);
                socket.receive(packet);

                String received = new String(packet.getData());
                System.out.println("Read: " + received);
            }
            socket.leaveGroup(group);
        }
    }

    @Override
    public void run() {
        try {
            System.out.println("Getting Carousel");
            //testWithMesages();
            MulticastSocket socket = new MulticastSocket(this.port);
            InetAddress group = InetAddress.getByName(this.address);
            socket.joinGroup(group);

            DatagramPacket packet;

            StreamObjectList objectList = new StreamObjectList();
            boolean isComplete = false;
            while (!isComplete) {
                byte[] buf = new byte[1024];
                packet = new DatagramPacket(buf, buf.length);
                socket.receive(packet);

                byte[] received = packet.getData();
                byte[] offset = new byte[2];
                System.arraycopy(received, 0, offset, 0, 2);

                byte[] total = new byte[2];
                System.arraycopy(received, 2, total, 0, 2);

                byte[] blockSize = new byte[2];
                System.arraycopy(received, 4, blockSize, 0, 2);
                
                byte[] filename = new byte[28];
                System.arraycopy(received, 6, filename, 0, 26);

                System.out.println("Read Offset: " + ByteArray.toInt(offset, 0, 2));
                System.out.println("Read total: " + ByteArray.toInt(total, 0, 2));
                System.out.println("Read size: " + ByteArray.toInt(blockSize, 0, 2));
                System.out.println("Read Offset: " + new String(filename).trim());
                
                String name = new String(filename).trim();
                StreamObject object = objectList.getByFilename(name);
                if(object==null){
                    object = new StreamObject(this.address,this.port, new String(filename).trim(), ByteArray.toInt(total, 0, 2));
                    objectList.add(object);
                }
                
                int receivedSize = ByteArray.toInt(blockSize, 0, 2);
                byte[] fileChunk = new byte[receivedSize];
                System.out.println(received.length);
                System.arraycopy(received, 32, fileChunk, 0, receivedSize);
                if(!object.addChunk(fileChunk, ByteArray.toInt(offset, 0, 2))){
                    //Se nao conseguir salvar, considera que estah completo.
                    if(object.isComplete()){
                        object.saveFile();
                    }
                }
            }
            socket.leaveGroup(group);
            socket.close();
        } catch (IOException ex) {
            Logger.getLogger(CarouselReader.class.getName()).log(Level.SEVERE, null, ex);
        }



    }
}
